using System.Collections.Generic;
using UnityEngine;
using UnityEngine.UI;

public class CrystalSkillController : Skill
{
    [SerializeField] private float duration;
    [SerializeField] private GameObject prefab;
    private GameObject crystal;
    [Header("Crystal simple")]
    [SerializeField] private UiSkillTreeSlot unlockCrystalButton;
    public bool CrystalUnlocked { get; private set; }
    [Header("Crystal mirage")]
    [SerializeField] private UiSkillTreeSlot unlockCloneInsteadButton;
    [SerializeField] private bool cloneInsteadOfCrystal;
    [Header("Explode crystal")]
    [SerializeField] private UiSkillTreeSlot unlockExplosiveButton;
    [SerializeField] private float explodeCooldown;
    [SerializeField] private bool canExplode;
    [Header("Moving crystal")]
    [SerializeField] private UiSkillTreeSlot unlockMovingCrystalButton;
    [SerializeField] private bool canMoveToEnemy;
    [SerializeField] private float moveSpeed;
    [Header("Multi stacking crystal")]
    [SerializeField] private UiSkillTreeSlot unlockMultiStackButton;
    [SerializeField] private bool canMultiCrystal;
    [SerializeField] private int maxStack;
    [SerializeField] private float multiStackCooldown;
    [SerializeField] private float useTimeWindow;
    [SerializeField] private List<GameObject> crystals = new();

    protected override void Start()
    {
        base.Start();
        unlockCrystalButton.GetComponent<Button>().onClick.AddListener(UnlockCrystal);
        unlockCloneInsteadButton.GetComponent<Button>().onClick.AddListener(UnlockCrystalMirage);
        unlockExplosiveButton.GetComponent<Button>().onClick.AddListener(UnlockExplosiveCrystal);
        unlockMovingCrystalButton.GetComponent<Button>().onClick.AddListener(UnlockMovingCrystal);
        unlockMultiStackButton.GetComponent<Button>().onClick.AddListener(UnlockMultiStack);
    }

    protected override void CheckUnlock()
    {
        UnlockCrystal();
        UnlockCrystalMirage();
        UnlockExplosiveCrystal();
        UnlockMovingCrystal();
        UnlockMultiStack();
    }

    private void UnlockCrystal()
    {
        if (!unlockCrystalButton.unlocked || CrystalUnlocked) return;
        CrystalUnlocked = true;
    }

    private void UnlockCrystalMirage()
    {
        if (!unlockCloneInsteadButton.unlocked || cloneInsteadOfCrystal) return;
        cloneInsteadOfCrystal = true;
    }

    private void UnlockExplosiveCrystal()
    {
        if (!unlockExplosiveButton.unlocked || canExplode) return;
        canExplode = true;
        cooldownTime = explodeCooldown;
    }

    private void UnlockMovingCrystal()
    {
        if (!unlockMovingCrystalButton.unlocked || canMoveToEnemy) return;
        canMoveToEnemy = true;
    }

    private void UnlockMultiStack()
    {
        if (!unlockMultiStackButton.unlocked || canMultiCrystal) return;
        canMultiCrystal = true;
    }

    public override void Use()
    {
        base.Use();
        if (CanUseMultiCrystals())
        {
            return;
        }

        if (!crystal)
        {
            Create();
        }
        else
        {
            if (canMoveToEnemy)
                return;

            Vector2 position = Player.transform.position;
            Player.SetPosition(crystal.transform.position);
            crystal.transform.position = position;
            if (cloneInsteadOfCrystal)
            {
                Player.SkillManager.Clone.Create(crystal.transform);
                Destroy(crystal);
            }
            else
            {
                crystal.GetComponent<CrystalSkill>()?.Completed();
            }
        }
    }

    public void Create()
    {
        crystal = Instantiate(prefab, Player.transform.position, Quaternion.identity);
        CrystalSkill skill = crystal.GetComponent<CrystalSkill>();
        skill.Setup(duration, canExplode, canMoveToEnemy, moveSpeed, FindClosestEnemy(skill.transform), Player);
    }

    public void CurrentCrystalChooseRandomEnemy()
    {
        crystal.GetComponent<CrystalSkill>().ChooseRandomEnemy();
    }

    private bool CanUseMultiCrystals()
    {
        if (!canMultiCrystal) return false;
        if (crystals.Count <= 0) return false;
        if (crystals.Count == maxStack)
        {
            Invoke(nameof(ResetAbility), useTimeWindow);
        }

        cooldownTime = 0f;
        GameObject prefab = crystals[crystals.Count - 1];
        GameObject obj = Instantiate(prefab, Player.transform.position, Quaternion.identity);
        _ = crystals.Remove(prefab);
        obj.GetComponent<CrystalSkill>().Setup(duration, canExplode, canMoveToEnemy, moveSpeed,
            FindClosestEnemy(obj.transform), Player);
        if (crystals.Count != 0) return true;
        cooldownTime = multiStackCooldown;
        RefillCrystal();

        return true;
    }

    /// <summary>
    /// 重新装填水晶
    /// </summary>
    private void RefillCrystal()
    {
        int addCount = maxStack - crystals.Count;
        for (int i = 0; i < addCount; i++)
        {
            crystals.Add(prefab);
        }
    }

    private void ResetAbility()
    {
        if (cooldownTimer > 0)
            return;

        cooldownTimer = multiStackCooldown;
        RefillCrystal();
    }
}